/**
 * tjftp -- A simple FTP server, using the ANSI C
 * Copyright (C) 2011  degui.chen <degui.chen@qq.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "settings.h"
#include "memory.h"
#include "unity.h"
void tj_settings_dump(PSettings settings) {
	printf("config_file	\t:%s\n", settings->config_file);
	printf("bind_port	\t:%i\n", settings->bind_port);
	printf("data_port	\t:%i\n", settings->data_port);
	printf("log_file	\t:%s\n", settings->log_file);
	printf("document_root	\t:%s\n", settings->document_root);
	printf("listen_queue_max_length\t:%i\n", settings->listen_queue_max_length);
	printf("max_process\t:%i\n", settings->max_process);
	printf("user id\t:%i\n", settings->uid);
	printf("group id\t:%i\n", settings->gid);
}
PSettings tj_settings_create(int argc, char* argv[]) {
	DEBUG_LOG("处理-配置参数的默认值", 1);
	PSettings settings = tj_settings_init();
	DEBUG_LOG("处理命令行选项", 1);
	tj_settings_cmd_opton(settings, argc, argv);
	DEBUG_LOG("读取配置文件信息", 1);
	tj_settings_file_option(settings);
	return settings;
}

PSettings tj_settings_init() {
	PSettings settings = (PSettings) tj_memory_alloc(sizeof(Settings));
	char config_path[] = "/etc/tftp.conf";
	tj_memory_copy(settings->config_file, config_path, strlen(config_path));
	char document_root[] = "/var/www";
	tj_memory_copy(settings->document_root, document_root, strlen(document_root));

	settings->listen_queue_max_length = 128;
	settings->bind_port = 21;
	settings->data_port = 20;
	settings->max_process = 3;
	settings->uid = getuid();
	settings->gid = getgid();
	return settings;
}
void tj_settings_destory(PSettings settings) {
	tj_memory_free(settings);
}
void tj_settings_cmd_opton(PSettings settings, int argc, char* argv[]) {
	const char* option_string = "f:h";//如果选项字符串里的字母后面接着 : , 表示还有相关的参数，全局变量 optarg 会指向这个额外参数。
	opterr = 0; // 0 不显示错误信息。

	int c;
	while ((c = getopt(argc, argv, option_string)) != EOF) {
		switch (c) {
			case 'f':
				memset(settings->config_file, '\0', strlen(settings->config_file) + 1);
				tj_memory_copy(settings->config_file, optarg, strlen(optarg));
				break;
			case 'h':
				tj_print_usage();
				exit(0);
				break;
			default:
				printf("error option : %c \n", c);
		}
	}
	if (tj_path_is_file(settings->config_file)) {
		printf("config file '%s' not exists.\n");
		exit(-1);
	}
}
void tj_settings_file_option(PSettings settings) {
	FILE* stream = fopen(settings->config_file, "r");
	if (stream == NULL)
		perror("Error opening file");
	else {
		fseek(stream, 0, SEEK_SET);
		char line[256];
		while (NULL != fgets(line, 256, stream)) {
			int index = tj_string_index(line, "=");
			if (index > 0) {
				char key[255] = { '\0' };
				tj_string_substr(line, 0, index, key);
				tj_string_trim(key);
				char value[255] = { '\0' };
				tj_string_substr(line, index + 1, strlen(line), value);
				tj_string_trim(value);
				if (!strcmp("bind_port", key)) {
					settings->bind_port = atoi(value);
				}
				if (!strcmp("data_port", key)) {
					settings->data_port = atoi(value);
				}
				if (!strcmp("log_file", key)) {
					//确保文件存在安全
					memset(settings->log_file, '\0', strlen(value) + 1);
					memcpy(settings->log_file, value, strlen(value));
				}
				if (!strcmp("document_root", key)) {
					//确保目录存在安全
					char* temp = realpath(value, NULL);
					memset(settings->document_root, '\0', strlen(temp) + 1);
					memcpy(settings->document_root, temp, strlen(temp));
				}
				if (!strcmp("max_process", key)) {
					settings->max_process = atoi(value);
					if (settings->max_process < 1) {
						settings->max_process = 1;
					}
				}
			}
		}
		fclose(stream);
	}
}
